/*	BuildRefinery class definition.
 *
*/

#include "BuildingPlacer.h"
#include "BuildRefinery.h"

void BuildRefinery::Enter()
{
	DEBUG_PRINT("BuildRefinery(%p) %s entering\n", this, GetName().c_str());

}

void BuildRefinery::Execute()
{
	DEBUG_PRINT("BuildRefinery(%p) %s executing\n", this, GetName().c_str());
	std::list<Base*>* bases = BB->GetBases();
	std::list<BWAPI::Unit*>* scvs;
	std::list<BWAPI::Unit*>::iterator scv;
	std::list<Geyser*>* geysers;
	std::list<Geyser*>::iterator geyser;
	if(!builder)
	{
		for(std::list<Base*>::iterator base = bases->begin(); base != bases->end(); base++)
		{
			geysers = (*base)->GetGeysers();
			if(geysers)
			{
				geyser = geysers->begin();
				scvs = (*base)->GetUnitsByType(BWAPI::UnitTypes::Terran_SCV);
				scv = scvs->begin();
				for(; scv != scvs->end(); scv++)
				{
					if (!builder)
					{		
						if (((*scv)->isGatheringMinerals() || (*scv)->isIdle()) && !(*scv)->isCarryingMinerals())
						{
							builder = *scv;
							break;
						}
					}
					else
						break;
				}
				for(; geyser != geysers->end(); geyser++)
				{
					if(!(*geyser)->refinery)
						break;
				}
				if(builder && (geyser!=geysers->end()))
					break;
			}
		}
		DEBUG_PRINT("BuildRefinery(%p) attempting to build with SCV(%p) at (%d,%d).\n", this, builder, (*geyser)->geyser->getTilePosition().x(), (*geyser)->geyser->getTilePosition().y());
		
		builder->build((*geyser)->geyser->getTilePosition(),BWAPI::UnitTypes::Terran_Refinery);
		(*geyser)->refinery = NULL;
		(*geyser)->gathering = 1;
		BB->ResetOrder();
	}
	else if(builder)
	{
		if(!builder->exists())
		{
			builder = NULL;
			BB->Refund(BWAPI::UnitTypes::Terran_Refinery);
		}
		else if (builder->isConstructing()&& builder->getBuildUnit())
			builder = NULL;
		else if (builder->getLastCommand().getType() == BWAPI::UnitCommandTypes::Build && !builder->getBuildUnit())
		{

		}
		else if(builder->getLastCommand().getType() != BWAPI::UnitCommandTypes::Build)
		{
			BB->Refund(BWAPI::UnitTypes::Terran_Refinery);
			builder = NULL;
		}
	}
	control->FinishWithSuccess();
}

void BuildRefinery::Exit()
{
	DEBUG_PRINT("BuildRefinery(%p) %s exiting\n", this, GetName().c_str());

}

bool BuildRefinery::CheckConditions()
{
	DEBUG_PRINT("BuildRefinery(%p) %s checking conditions\n", this, GetName().c_str());
	std::list<Base*>* bases = BB->GetBases();
	bool condition = false;
	std::list<BWAPI::Unit*>* bar = BB->GetBuildingsByTypeGeneral(BWAPI::UnitTypes::Terran_Barracks);
	if(bar && bar->size()>0)
	{
		bool haveBarracks = false;
		for(std::list<BWAPI::Unit*>::iterator it = bar->begin(); it != bar->end(); it++)
		{
			if((*it)->isCompleted())
			{
				haveBarracks = true;
				break;
			}
		}
		if(haveBarracks)
		{
			for(std::list<Base*>::iterator base = bases->begin(); base != bases->end(); base++)
			{
				if((*base)->NeedMoreGas() && BWAPI::Broodwar->self()->minerals() > BWAPI::UnitTypes::Terran_Refinery.mineralPrice())
				{
					//if(BB->isBuildBuilding(BWAPI::UnitTypes::Terran_Refinery))
					//{
					
						DEBUG_PRINT("BuildRefinery(%p) %s checked conditions and has %d minerals to spend\n", this, GetName().c_str(), BB->GetMineralsToSpend());
						//BB->SpendResources(BWAPI::UnitTypes::Terran_Refinery);
						condition = true;
					//}
				}
				return condition;
			}
		}
	}
	return condition;
}